package com.bwda.dsrs.filecenter.util;

import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 密码生成器
 * 
 * @author wanghui
 * 
 * 
 */
public class PasswordBuilder {
    private static Pattern numberPattern = Pattern.compile(".*\\d+.*");
	
	/**
	 * 根据密码生成的规则生成密码
	 * 
	 */
	public static String createPwdNew(int pwdMinLength, int pwdMaxLength, boolean includeLetter, boolean includeNumber,
	        boolean includeSpecial, boolean includeCapital,String forbitChar){
	   //判断禁用字符是否为空
		if(forbitChar == null || "".equals(forbitChar)){
			//用老方法生成密码
			return createPwd(pwdMinLength, pwdMaxLength,
							  includeLetter, includeNumber, includeSpecial,
							  includeCapital);
		}
	   //获取要生成的密码长度
	     int length = pwdMinLength;
	     String str = "";
	     Random r = new Random();
	     if(includeSpecial || includeNumber || includeCapital || includeLetter){
	    	//如果 
		     boolean flag = true;
		     String code =  "";
	    	 while(flag){
	    		 //随机，如果为false 则判断是否为小写
	    		 if(r.nextBoolean()){
	    			 if(r.nextBoolean()){
	    				 if(r.nextBoolean()){
	    					 //判断是否为特殊字符
	    					 if (includeSpecial) {
	                                code = createSpecialWithLength(1);
	                         }
	    				 } else{
	    					 //判断是否为数字
	    					 if(includeNumber){
	    		    			 code = createNumWithLength(1);
	    		    		 }
	    				 }
	    			 }else{
	    				 //判断是否是大写
	    				 if(includeCapital){
	    					 code = createCapitalWithLength(1);
	    	    		 } 
	    			 }
	    		 }else{
	    			 //判断是否为小写
	    			 if (includeLetter) {
	                    code = createLetterWithLength(1);
	                 }	 
	    		 }
	    		 //验证判断
	    		 if(!validateForbit(code,forbitChar)){
                 	str += code;
                 }
	    		 
	    		 //判断生成的字符是否大于密码长度，如果大于或者等于则将flag设置成false，跳出循环
	    		 //返回
	    		 if(str.length() >= length){
	    			 flag = false;
	    		 }
	    		 
		    	 
		     }
	    	 
	    	 return str;
	     }
	    return "";
	}
	
	
	//判断该字符是否在禁用字符中
	/**
	 * 1, 如果禁用字符为null或者为空字符换，则返回false,说明不存在
	 * 2, 判断随机生成的字符是否在禁用字符列表中，如果存在，则返回true，
	 * 3, 如果不存在，则返回false
	 */
	public static boolean validateForbit(String str, String forbitChar ){
		if(forbitChar == null || "".equals(forbitChar)){
			return false;
		}
		
		if(forbitChar.indexOf(str) > -1){
			return true;
		}
		    return false;
	}

    /**
     * 根据条件生成密码
     * 
     * @param pwdMinLength 密码最小长度
     * @param pwdMaxLength 密码最大长度
     * @param includeLetter 是否包含字母 1包含 0不包含
     * @param includeNumber 是否包含数字 1包含 0不包含
     * @param includeSpecial 是否包含特殊字符 1包含 0不包含
     * @param includeCapital 是否包含大写字母 1包含 0不包含
     * @return 出现异常返回sortec
     */
    public static String createPwd(int pwdMinLength, int pwdMaxLength, boolean includeLetter, boolean includeNumber,
        boolean includeSpecial, boolean includeCapital) {
        int length = pwdMinLength;
        String str = "";
        Random r = new Random();
        if (includeSpecial || includeNumber || includeCapital || includeLetter) {
            for (int i = 0; i < length; i++) {
                String code;
                if (r.nextBoolean()) {
                    if (r.nextBoolean()) {
                        if (r.nextBoolean()) {
                            if (includeSpecial) {
                                code = createSpecialWithLength(1);
                                str += code;
                            }
                            else {
                                i--;
                            }
                        }
                        else {
                            if (includeNumber) {
                                code = createNumWithLength(1);
                                str += code;
                            }
                            else {
                                i--;
                            }
                        }
                    }
                    else {
                        if (includeLetter) {
                            code = createLetterWithLength(1);
                            str += code;
                        }
                        else {
                            i--;
                        }
                    }
                }
                else {
                    if (includeCapital) {
                        code = createCapitalWithLength(1);
                        str += code;
                    }
                    else {
                        i--;
                    }
                }
                
            }
            //判断生成的str是否符合规则
            if((includeLetter && !checkLetter(str)) 
            	|| (includeNumber && !checkNumbers(str))
            	|| (includeSpecial && !checkSpecial(str))
            	|| (includeCapital && !checkCapital(str))
            	) {
            	str = createPwd(pwdMinLength, pwdMaxLength, includeLetter, includeNumber, includeSpecial, includeCapital);
            }
            return str;
        }
        return "mcafee123!@#";
    }
    
    /**
     * 生成指定长度的特殊字符
     * 
     * @param num
     * @return
     */
    public static String createSpecialWithLength(int num) {
        String str = "";
        for (int i = 0; i < num; i++) {
            int code = createNumByRange(33, 47);
            str += (char)code;
        }
        return str;
    }
    
    /**
     * 生成指定长度的小写字母
     * 
     * @param num
     * @return
     */
    public static String createLetterWithLength(int num) {
        String str = "";
        for (int i = 0; i < num; i++) {
            int code = createNumByRange(97, 122);
            str += (char)code;
        }
        return str;
    }
    
    /**
     * 生成指定长度的大写字母
     * 
     * @param num
     * @return
     */
    public static String createCapitalWithLength(int num) {
        String str = "";
        for (int i = 0; i < num; i++) {
            int code = createNumByRange(65, 90);
            str += (char)code;
        }
        return str;
    }
    
    /**
     * 生成指定长度的数字
     * 
     * @param num
     * @return
     */
    public static String createNumWithLength(int num) {
        String str = "";
        for (int i = 0; i < num; i++) {
            int code = new Random().nextInt(10);
            str += code;
        }
        
        return str;
    }
    
    /**
     * 生成指定范围内的随机数，包含界限
     * 
     * @param min
     * @param max
     * @return
     */
    public static int createNumByRange(int min, int max) {
        return (int)Math.round(Math.random() * (max - min) + min);
    }
    
    public static String createDefaultPwd() {
        return createPwd(6, 10, true, true, true, true);
    }
    
    public static void main(String[] args) {
//        for (int i = 47; i >= 33; i--) {
//            System.out.println("mcaff123" + (char)i);
//        }
    	//字母, 数字, 特殊, 大写
    	for(int j=0; j <= 10;j++) {
    		String content = createPwd(8, 10, false, false, true, false);
    		System.out.println("content:"+content);
    	}
    	
    }
    
    /**
     * 是否包含数字
     * @param content
     * @return true: 包含字母 ;false 不包含字母
     */
    public static boolean checkNumbers(String content) {
    	Matcher m = numberPattern.matcher(content);
    	return m.matches();
    }
    
    /**
     * 是否包含字母
     * @param content
     * @return true: 包含字母 ;false 不包含字母
     */
    public static boolean checkLetter(String content) {  
        String regex=".*[a-zA-Z]+.*";  
        Matcher m=Pattern.compile(regex).matcher(content);  
        return m.matches();  
    }
    
    /**
     * 是否包含大写字母
     * @param content
     * @return true: 包含字母 ;false 不包含字母
     */
    public static boolean checkCapital(String content) {  
        String regex=".*[A-Z]+.*";
        Matcher m=Pattern.compile(regex).matcher(content);  
        return m.matches();  
    }
    
    /**
     * 是否包含特殊字符
     * @param content
     * @return true: 包含字母 ;false 不包含字母
     */
    public static boolean checkSpecial(String content) {  
    	String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？-]";
    	Pattern p=Pattern.compile(regEx);
    	Matcher m=p.matcher(content);
        return m.find();
    }
}
